home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / proc / procStubs.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  28KB  |  1,200 lines

  1. /* 
  2.  * procStubs.c --
  3.  *
  4.  *    Stubs for Unix compatible system calls.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/proc/procStubs.c,v 1.6 91/11/11 15:07:14 shirriff Exp $";
  18. #endif /* not lint */
  19.  
  20. #define MACH_UNIX_COMPAT
  21.  
  22. #include <sprite.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <status.h>
  26. #include <errno.h>
  27. #include <procUnixStubs.h>
  28. #include <user/sys/types.h>
  29. #include <user/sys/wait.h>
  30. #include <user/sys/time.h>
  31. #include <user/sys/resource.h>
  32. #include <mach.h>
  33. #include <proc.h>
  34. #include <procInt.h>
  35. #include <vm.h>
  36. #include <fsutil.h>
  37. #include <assert.h>
  38.  
  39. int debugProcStubs;
  40.  
  41. #if defined(ds3100) || defined(ds5000)
  42. extern Mach_State *machCurStatePtr;
  43. #endif
  44.  
  45. /*
  46.  *----------------------------------------------------------------------
  47.  *
  48.  * copyin --
  49.  *
  50.  *    Copys a string from user space.
  51.  *
  52.  * Results:
  53.  *    Returns string.
  54.  *
  55.  * Side effects:
  56.  *    Copies the string.
  57.  *     
  58.  *
  59.  *----------------------------------------------------------------------
  60.  */
  61. static char *
  62. copyin(string)
  63.     char *string;
  64. {
  65.     static char buf[FS_MAX_PATH_NAME_LENGTH + 1];
  66.     int x;
  67.  
  68.     assert(debugProcStubs);
  69.     Fsutil_StringNCopy(FS_MAX_PATH_NAME_LENGTH, string, buf, &x);
  70.     return buf;
  71. }
  72.  
  73. /*
  74.  *----------------------------------------------------------------------
  75.  *
  76.  * Proc_ExitStub --
  77.  *
  78.  *    The stub for the "exit" Unix system call.
  79.  *
  80.  * Results:
  81.  *    Returns -1 on failure.
  82.  *
  83.  * Side effects:
  84.  *    Side effects associated with the system call.
  85.  *     
  86.  *
  87.  *----------------------------------------------------------------------
  88.  */
  89. int
  90. Proc_ExitStub(arg0)
  91.     int arg0;
  92. {
  93.  
  94.     if (debugProcStubs) {
  95.     printf("Proc_ExitStub(0x%x)\n", arg0);
  96.     }
  97.     Proc_Exit(arg0);
  98.     return -1;
  99. }
  100. /*
  101.  *----------------------------------------------------------------------
  102.  *
  103.  * Proc_ForkStub --
  104.  *
  105.  *    The stub for the "fork" Unix system call.
  106.  *
  107.  * Results:
  108.  *    Returns -1 on failure.
  109.  *
  110.  * Side effects:
  111.  *    Side effects associated with the system call.
  112.  *     
  113.  *
  114.  *----------------------------------------------------------------------
  115.  */
  116. int
  117. Proc_ForkStub()
  118. {
  119.     ReturnStatus    status;
  120.     Proc_PID newPid;
  121.  
  122.     if (debugProcStubs) {
  123.     printf("Proc_ForkStub\n");
  124.     }
  125.     /*
  126.      * Make sure Proc_NewProc knows we're a compatibility process.
  127.      */
  128.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_UNIX;
  129. #if defined(ds3100) || defined(ds5000)
  130.     /*
  131.      * Put the right values in V1 and A3 for the child because the process
  132.      * jumps directly to user space after it is created.  A 1 in v1 
  133.      * is what the system call stub in the user process expects for the
  134.      * child.
  135.      */
  136.     machCurStatePtr->userState.regState.regs[V1] = 1;
  137.     machCurStatePtr->userState.regState.regs[A3] = 0;
  138. #else
  139.     Mach_Return2(1);
  140. #endif
  141.     status = Proc_NewProc((Address) 0, PROC_USER, FALSE, &newPid,
  142.               (char *) NIL, FALSE);
  143.     if (status == PROC_CHILD_PROC) {
  144.     panic("Proc_ForkStub: Child came alive here?\n");
  145.     }
  146.     if (status != SUCCESS) {
  147.     Mach_SetErrno(Compat_MapCode(status));
  148.     return -1;
  149.     }
  150. #if defined(ds3100) || defined(ds5000)
  151.     machCurStatePtr->userState.regState.regs[V1] = 0;
  152. #else
  153.     Mach_Return2(0);
  154. #endif
  155.     return (int) newPid;
  156. }
  157.  
  158. int
  159. Proc_VforkStub()
  160. {
  161.     ReturnStatus    status;
  162.     Proc_PID newPid;
  163.  
  164.     if (debugProcStubs) {
  165.     printf("Proc_VForkStub\n");
  166.     }
  167.     /*
  168.      * Make sure Proc_NewProc knows we're a compatibility process.
  169.      */
  170.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_UNIX;
  171. #if defined(ds3100) || defined(ds5000)
  172.     /*
  173.      * Put the right values in V1 and A3 for the child because the process
  174.      * jumps directly to user space after it is created.  A 1 in v1 
  175.      * is what the system call stub in the user process expects for the
  176.      * child.
  177.      */
  178.     machCurStatePtr->userState.regState.regs[V1] = 1;
  179.     machCurStatePtr->userState.regState.regs[A3] = 0;
  180. #else
  181.     Mach_Return2(1);
  182. #endif
  183.     status = Proc_NewProc(0, PROC_USER, FALSE, &newPid,
  184.               (char *) NIL, TRUE);
  185.     if (status != SUCCESS) {
  186.     Mach_SetErrno(Compat_MapCode(status));
  187.     return -1;
  188.     }
  189. #if defined(ds3100) || defined(ds5000)
  190.     machCurStatePtr->userState.regState.regs[V1] = 0;
  191. #else
  192.     Mach_Return2(0);
  193. #endif
  194.     return (int) newPid;
  195. }
  196.  
  197.  
  198. /*
  199.  *----------------------------------------------------------------------
  200.  *
  201.  * Proc_ExecveStub --
  202.  *
  203.  *    The stub for the "execve" Unix system call.
  204.  *
  205.  * Results:
  206.  *    Returns -1 on failure.
  207.  *
  208.  * Side effects:
  209.  *    Side effects associated with the system call.
  210.  *     
  211.  *
  212.  *----------------------------------------------------------------------
  213.  */
  214. int
  215. Proc_ExecveStub(name, argv, envp)
  216.     char *name;            /* name of file to exec */
  217.     char **argv;        /* array of arguments */
  218.     char **envp;        /* array of environment pointers */
  219. {
  220.     ReturnStatus status;
  221.  
  222.     if (debugProcStubs) {
  223.     printf("Proc_ExecveStub(%s)\n", copyin(name));
  224.     }
  225.     status = Proc_ExecEnv(name, argv, envp, FALSE);
  226.     Mach_SetErrno(Compat_MapCode(status));
  227.     return -1;
  228. }
  229.  
  230.  
  231. /*
  232.  *----------------------------------------------------------------------
  233.  *
  234.  * Proc_ExecvStub --
  235.  *
  236.  *    The stub for the "execv" Unix system call.
  237.  *
  238.  * Results:
  239.  *    Returns -1 on failure.
  240.  *
  241.  * Side effects:
  242.  *    Side effects associated with the system call.
  243.  *     
  244.  *
  245.  *----------------------------------------------------------------------
  246.  */
  247. int
  248. Proc_ExecvStub(name, argv)
  249.     char *name;            /* Name of file containing program to exec. */
  250.     char **argv;        /* Array of arguments to pass to program. */
  251. {
  252.     ReturnStatus status;
  253.  
  254.     if (debugProcStubs) {
  255.     printf("Proc_ExecvStub(%s)\n", copyin(name));
  256.     }
  257.     status = Proc_Exec(name, argv, USER_NIL, FALSE, 0);
  258.     Mach_SetErrno(Compat_MapCode(status));
  259.     return -1;
  260. }
  261.  
  262.  
  263. /*
  264.  *----------------------------------------------------------------------
  265.  *
  266.  * Proc_GetpidStub --
  267.  *
  268.  *    The stub for the "getpid" Unix system call.
  269.  *
  270.  * Results:
  271.  *    Returns -1 on failure.
  272.  *
  273.  * Side effects:
  274.  *    Side effects associated with the system call.
  275.  *     
  276.  *
  277.  *----------------------------------------------------------------------
  278.  */
  279. int
  280. Proc_GetpidStub()
  281. {
  282.  
  283.     if (debugProcStubs) {
  284.     printf("Proc_GetpidStub: %x\n", Proc_GetEffectiveProc()->processID);
  285.     }
  286.     Mach_Return2(Proc_GetEffectiveProc()->parentID);
  287.     return Proc_GetEffectiveProc()->processID;
  288. }
  289.  
  290.  
  291. /*
  292.  *----------------------------------------------------------------------
  293.  *
  294.  * Proc_GetuidStub --
  295.  *
  296.  *    The stub for the "getuid" Unix system call.
  297.  *
  298.  * Results:
  299.  *    Returns -1 on failure.
  300.  *
  301.  * Side effects:
  302.  *    Side effects associated with the system call.
  303.  *     
  304.  *
  305.  *----------------------------------------------------------------------
  306.  */
  307. int
  308. Proc_GetuidStub()
  309. {
  310.     Proc_ControlBlock *procPtr = Proc_GetEffectiveProc();
  311.     int uid,euid;
  312.  
  313.     if (debugProcStubs) {
  314.     printf("Proc_GetuidStub\n");
  315.     }
  316.     uid = procPtr->userID;
  317.     euid = procPtr->effectiveUserID;
  318.     /*
  319.      * We have to return the effective user id via Mach_Return2.
  320.      */
  321.     Mach_Return2(euid);
  322.     return uid;
  323. }
  324.  
  325.  
  326.  
  327. /*
  328.  *----------------------------------------------------------------------
  329.  *
  330.  * Proc_PtraceStub --
  331.  *
  332.  *    The stub for the "ptrace" Unix system call.
  333.  *
  334.  * Results:
  335.  *    Returns -1 on failure.
  336.  *
  337.  * Side effects:
  338.  *    Side effects associated with the system call.
  339.  *     
  340.  *
  341.  *----------------------------------------------------------------------
  342.  */
  343. /*ARGSUSED*/
  344. int
  345. Proc_PtraceStub(request, pid, addr, data)
  346.     int request, pid, *addr, data;
  347. {
  348.  
  349.     printf("ptrace is not implemented\n");
  350.     Mach_SetErrno(EINVAL);
  351.     return -1;
  352. }
  353.  
  354.  
  355. /*
  356.  *----------------------------------------------------------------------
  357.  *
  358.  * Proc_GetgidStub --
  359.  *
  360.  *    The stub for the "getgid" Unix system call.
  361.  *
  362.  * Results:
  363.  *    Returns -1 on failure.
  364.  *
  365.  * Side effects:
  366.  *    Side effects associated with the system call.
  367.  *     
  368.  *
  369.  *----------------------------------------------------------------------
  370.  */
  371. int
  372. Proc_GetgidStub()
  373. {
  374.  
  375.     /*
  376.      * The Sprite group id for Sprite at Berkeley.  Should do a better job
  377.      * of this.
  378.      */
  379.     if (debugProcStubs) {
  380.     printf("Proc_GetgidStub\n");
  381.     }
  382.     /*
  383.      * We have to return the effective group id via Mach_Return2.
  384.      */
  385.     Mach_Return2(155);
  386.     return 155;
  387. }
  388.  
  389.  
  390.  
  391. /*
  392.  *----------------------------------------------------------------------
  393.  *
  394.  * Proc_UmaskStub --
  395.  *
  396.  *    The stub for the "umask" Unix system call.
  397.  *
  398.  * Results:
  399.  *    Returns -1 on failure.
  400.  *
  401.  * Side effects:
  402.  *    Side effects associated with the system call.
  403.  *     
  404.  *
  405.  *----------------------------------------------------------------------
  406.  */
  407. int
  408. Proc_UmaskStub(newPerm)
  409.     unsigned int newPerm;
  410. {
  411.     unsigned int        oldPerm;
  412.     Proc_ControlBlock    *procPtr;
  413.  
  414.     if (debugProcStubs) {
  415.     printf("Proc_UmaskStub(0x%x)\n", newPerm);
  416.     }
  417.     procPtr = Proc_GetEffectiveProc();
  418.     oldPerm = procPtr->fsPtr->filePermissions;
  419.     procPtr->fsPtr->filePermissions = ~newPerm & 0777;
  420.     return ~oldPerm & 0x777;
  421. }
  422.  
  423.  
  424.  
  425. /*
  426.  *----------------------------------------------------------------------
  427.  *
  428.  * Proc_GetgroupsStub --
  429.  *
  430.  *    The stub for the "getgroups" Unix system call.
  431.  *
  432.  * Results:
  433.  *    Returns -1 on failure.
  434.  *
  435.  * Side effects:
  436.  *    Side effects associated with the system call.
  437.  *     
  438.  *
  439.  *----------------------------------------------------------------------
  440.  */
  441. int
  442. Proc_GetgroupsStub(gidsetlen, gidset)
  443.     int gidsetlen;
  444.     int *gidset;
  445. {
  446.     int trueGidlen;
  447.     register    Fs_ProcessState     *fsPtr;
  448.  
  449.     if (debugProcStubs) {
  450.     printf("Proc_GetgroupsStub\n");
  451.     }
  452.     fsPtr = (Proc_GetEffectiveProc())->fsPtr;
  453.  
  454.     if (gidsetlen < 0) {
  455.     Mach_SetErrno(EINVAL);
  456.     return -1;
  457.     }
  458.     trueGidlen = gidsetlen < fsPtr->numGroupIDs ? gidsetlen:fsPtr->numGroupIDs;
  459.     if (trueGidlen > 0 && gidset != USER_NIL) {
  460.     if (Proc_ByteCopy(FALSE, trueGidlen * sizeof(int),
  461.                       (Address) fsPtr->groupIDs,
  462.               (Address) gidset) != SUCCESS) {
  463.             Mach_SetErrno(EFAULT);
  464.         return -1;
  465.     }
  466.     }
  467.     return trueGidlen;
  468. }
  469.  
  470.  
  471. /*
  472.  *----------------------------------------------------------------------
  473.  *
  474.  * Proc_SetgroupsStub --
  475.  *
  476.  *    The stub for the "setgroups" Unix system call.
  477.  *
  478.  * Results:
  479.  *    Returns -1 on failure.
  480.  *
  481.  * Side effects:
  482.  *    Side effects associated with the system call.
  483.  *     
  484.  *
  485.  *----------------------------------------------------------------------
  486.  */
  487. int
  488. Proc_SetgroupsStub(ngroups, gidset)
  489.     int ngroups;
  490.     int *gidset;
  491. {
  492.     ReturnStatus status;
  493.  
  494.     if (debugProcStubs) {
  495.     printf("Proc_SetgroupsStub\n");
  496.     }
  497.     status = Proc_SetGroupIDs(ngroups, gidset);
  498.     if (status != SUCCESS) {
  499.     Mach_SetErrno(Compat_MapCode(status));
  500.     return -1;
  501.     }
  502.     return 0;
  503. }
  504.  
  505.  
  506. /*
  507.  *----------------------------------------------------------------------
  508.  *
  509.  * Proc_GetpgrpStub --
  510.  *
  511.  *    The stub for the "getpgrp" Unix system call.
  512.  *
  513.  * Results:
  514.  *    Returns -1 on failure.
  515.  *
  516.  * Side effects:
  517.  *    Side effects associated with the system call.
  518.  *     
  519.  *
  520.  *----------------------------------------------------------------------
  521.  */
  522. int
  523. Proc_GetpgrpStub(pid)
  524.     Proc_PID    pid;
  525. {
  526.     ReturnStatus        status;
  527.     Proc_PID            familyID;
  528.     Proc_ControlBlock     *procPtr;
  529.  
  530.     if (debugProcStubs) {
  531.     printf("Proc_GetpgrpStub\n");
  532.     }
  533.     if (pid == 0 || pid == PROC_MY_PID) {
  534.     procPtr = Proc_GetEffectiveProc();
  535.     Proc_Lock(procPtr);
  536.     } else {
  537.     /*
  538.      *   Get the PCB entry for the given process.
  539.      */
  540.     procPtr = Proc_LockPID(pid);
  541.     status = SUCCESS;
  542.     if (procPtr == (Proc_ControlBlock *) NIL) {
  543.         status = PROC_INVALID_PID;
  544.     } else if (!Proc_HasPermission(procPtr->effectiveUserID)) {
  545.         Proc_Unlock(procPtr);
  546.         status = PROC_UID_MISMATCH;
  547.     }
  548.     if (status != SUCCESS) {
  549.         Mach_SetErrno(Compat_MapCode(status));
  550.         return -1;
  551.     }
  552.     }
  553.     familyID = procPtr->familyID;
  554.     Proc_Unlock(procPtr);
  555.     return familyID;
  556. }
  557.  
  558.  
  559. /*
  560.  *----------------------------------------------------------------------
  561.  *
  562.  * Proc_SetpgrpStub --
  563.  *
  564.  *    The stub for the "setpgrp" Unix system call.
  565.  *
  566.  * Results:
  567.  *    Returns -1 on failure.
  568.  *
  569.  * Side effects:
  570.  *    Side effects associated with the system call.
  571.  *     
  572.  *
  573.  *----------------------------------------------------------------------
  574.  */
  575. int
  576. Proc_SetpgrpStub(pid, pgrp)
  577.     int pid;
  578.     int pgrp;
  579. {
  580.     ReturnStatus status;
  581.  
  582.     if (debugProcStubs) {
  583.     printf("Proc_SetpgrpStub\n");
  584.     }
  585.     if (pid == 0) {
  586.     pid = PROC_MY_PID;
  587.     }
  588.     status = Proc_SetFamilyID(pid, pgrp);
  589.     if (status != SUCCESS) {
  590.     Mach_SetErrno(Compat_MapCode(status));
  591.     return -1;
  592.     }
  593.     return 0;
  594. }
  595.  
  596.  
  597. /*
  598.  *----------------------------------------------------------------------
  599.  *
  600.  * Proc_Wait4Stub --
  601.  *
  602.  *    The stub for the "wait4" Unix system call.
  603.  *
  604.  * Results:
  605.  *    Returns -1 on failure.
  606.  *
  607.  * Side effects:
  608.  *    Side effects associated with the system call.
  609.  *     
  610.  *
  611.  *----------------------------------------------------------------------
  612.  */
  613. int
  614. Proc_Wait4Stub(pid, statusPtr, options, unixRusagePtr)
  615.     int            pid;
  616.     union    wait    *statusPtr;
  617.     int            options;
  618.     struct    rusage    *unixRusagePtr;
  619. {
  620.     ReturnStatus        status;
  621.     int                    flags;
  622.     union wait          waitStatus;
  623.     struct    rusage    unixRusage;
  624.     Proc_ControlBlock    *curProcPtr;
  625.     ProcChildInfo    childInfo;
  626.     Proc_ResUsage     resUsage;
  627.     extern ReturnStatus DoWait();
  628.     extern ReturnStatus Compat_SpriteSignalToUnix();
  629.     int            numPids = 0;
  630.     Proc_PID        *pidArray = 0;
  631.  
  632.     if (debugProcStubs) {
  633.     printf("Proc_Wait4Stub(%x, %x, %x, %x)\n", pid, statusPtr, options,
  634.         unixRusagePtr);
  635.     }
  636.  
  637.     if (pid<0) {
  638.     printf("Proc_Wait4Stub: wait on pgrp not implemented\n");
  639.     Mach_SetErrno(EINVAL);
  640.     return -1;
  641.     } else if (pid != 0) {
  642.     pidArray = (Proc_PID *)&pid;
  643.     numPids = 1;
  644.     }
  645.  
  646.     flags = 0;
  647.     if (!(options & WNOHANG)) {
  648.     flags |= PROC_WAIT_BLOCK;
  649.     }
  650.     if (options & WUNTRACED) {
  651.     flags |= PROC_WAIT_FOR_SUSPEND;
  652.     }
  653.     curProcPtr = Proc_GetCurrentProc();
  654.     if (curProcPtr->genFlags & PROC_FOREIGN) {
  655.     status = ProcRemoteWait(curProcPtr, flags, numPids,
  656.                             pidArray, &childInfo);
  657.     } else {
  658.     status = DoWait(curProcPtr, flags, numPids, pidArray, &childInfo);
  659.     }
  660.  
  661.     if (debugProcStubs) {
  662.     printf("Proc_Wait4Stub: status = %x, child pid = %x, status = %x, code = %x\n",
  663.         status, childInfo.processID,  childInfo.termStatus,
  664.         childInfo.termCode);
  665.     }
  666.  
  667.     if (status == GEN_ABORTED_BY_SIGNAL) {
  668.     if (debugProcStubs) {
  669.         printf("Wait interrupted by signal\n");
  670.     }
  671.     curProcPtr->unixProgress = PROC_PROGRESS_RESTART;
  672.     return 0;
  673.     } else if (status != SUCCESS) {
  674.     if (status == PROC_NO_EXITS && (options & WNOHANG)) {
  675.         if (debugProcStubs) {
  676.         printf("Proc_Wait4Stub: exiting\n");
  677.         }
  678.         return 0;
  679.     }
  680.     Mach_SetErrno(ECHILD);
  681.     return -1;
  682.     }
  683.     if (statusPtr != NULL)  {
  684.     int    unixSignal;
  685.  
  686.     waitStatus.w_status = 0;
  687.     if (childInfo.termReason == PROC_TERM_SUSPENDED) {
  688.         (void)Compat_SpriteSignalToUnix(childInfo.termStatus, &unixSignal);
  689.         waitStatus.w_stopval = WSTOPPED;
  690.         waitStatus.w_stopsig = unixSignal;
  691.     } else if (childInfo.termReason == PROC_TERM_SIGNALED ||
  692.            childInfo.termReason == PROC_TERM_RESUMED) {
  693.         (void)Compat_SpriteSignalToUnix(childInfo.termStatus, &unixSignal);
  694.         waitStatus.w_termsig = unixSignal;
  695.         /* NEED TO HANDLE coredump FIELD */
  696.     } else {
  697.         waitStatus.w_retcode = childInfo.termStatus;
  698.     }
  699.     status = Vm_CopyOut(sizeof(waitStatus), (Address)&waitStatus,
  700.                 (Address)statusPtr);
  701.     if (status != SUCCESS) {
  702.         Mach_SetErrno(EFAULT);
  703.         return -1;
  704.     }
  705.     }
  706.     if (unixRusagePtr != NULL) {
  707.     Time totalKTime;
  708.     Time totalUTime;
  709.  
  710.     /*
  711.      * Convert the usages from the internal Timer_Ticks format
  712.      * into the external Time format.
  713.      */
  714.     Timer_TicksToTime(childInfo.kernelCpuUsage, &resUsage.kernelCpuUsage);
  715.     Timer_TicksToTime(childInfo.userCpuUsage, &resUsage.userCpuUsage);
  716.     Timer_TicksToTime(childInfo.childKernelCpuUsage, 
  717.                       &resUsage.childKernelCpuUsage);
  718.         Timer_TicksToTime(childInfo.childUserCpuUsage,
  719.                   &resUsage.childUserCpuUsage);
  720.     resUsage.numQuantumEnds = childInfo.numQuantumEnds;
  721.     resUsage.numWaitEvents = childInfo.numWaitEvents;
  722.     /*
  723.      * Return the total time used by the process and all its children.
  724.      */
  725.     bzero((char *) &unixRusage, sizeof(*unixRusagePtr));
  726.     Time_Add(resUsage.userCpuUsage, resUsage.childUserCpuUsage,
  727.                         &totalUTime);
  728.     Time_Add(resUsage.kernelCpuUsage,
  729.          resUsage.childKernelCpuUsage, &totalKTime);
  730.     unixRusage.ru_utime.tv_sec = totalUTime.seconds;
  731.     unixRusage.ru_utime.tv_usec = totalUTime.microseconds;
  732.     unixRusage.ru_stime.tv_sec = totalKTime.seconds;
  733.     unixRusage.ru_stime.tv_usec = totalKTime.microseconds;
  734.     unixRusage.ru_nvcsw = resUsage.numWaitEvents;
  735.     unixRusage.ru_nivcsw = resUsage.numQuantumEnds;
  736.     status = Vm_CopyOut(sizeof(unixRusage), (Address)&unixRusage,
  737.                 (Address)unixRusagePtr);
  738.     if (status != SUCCESS) {
  739.         Mach_SetErrno(EFAULT);
  740.         return -1;
  741.     }
  742.     }
  743.     if (debugProcStubs) {
  744.     printf("Proc_Wait4Stub: returning %x\n", childInfo.processID);
  745.     }
  746.     Mach_Return2(*(int *)&waitStatus);
  747.     return childInfo.processID;
  748. }
  749.  
  750.  
  751.  
  752. /*
  753.  *----------------------------------------------------------------------
  754.  *
  755.  * Proc_SetpriorityStub --
  756.  *
  757.  *    The stub for the "setpriority" Unix system call.
  758.  *
  759.  * Results:
  760.  *    Returns -1 on failure.
  761.  *
  762.  * Side effects:
  763.  *    Side effects associated with the system call.
  764.  *     
  765.  *
  766.  *----------------------------------------------------------------------
  767.  */
  768. /*ARGSUSED*/
  769. int
  770. Proc_SetpriorityStub(which, who, prio)
  771.     int which, who, prio;
  772. {
  773.  
  774.     printf("Proc_Setpriority not implemented\n");
  775.     return 0;
  776. }
  777.  
  778.  
  779. /*
  780.  *----------------------------------------------------------------------
  781.  *
  782.  * Proc_GetpriorityStub --
  783.  *
  784.  *    The stub for the "getpriority" Unix system call.
  785.  *
  786.  * Results:
  787.  *    Returns -1 on failure.
  788.  *
  789.  * Side effects:
  790.  *    Side effects associated with the system call.
  791.  *     
  792.  *
  793.  *----------------------------------------------------------------------
  794.  */
  795. /*ARGSUSED*/
  796. int
  797. Proc_GetpriorityStub(which, who, prio)
  798.     int which, who, prio;
  799. {
  800.  
  801.     printf("Proc_GetpriorityStub not implemented\n");
  802.     return 0;
  803. }
  804.  
  805.  
  806.  
  807. /*
  808.  *----------------------------------------------------------------------
  809.  *
  810.  * Proc_SetreuidStub --
  811.  *
  812.  *    The stub for the "setreuid" Unix system call.
  813.  *
  814.  * Results:
  815.  *    Returns -1 on failure.
  816.  *
  817.  * Side effects:
  818.  *    Side effects associated with the system call.
  819.  *     
  820.  *
  821.  *----------------------------------------------------------------------
  822.  */
  823. int
  824. Proc_SetreuidStub(userID, effUserID)
  825.     int     userID;
  826.     int     effUserID;
  827. {
  828.     ReturnStatus    status;
  829.     Proc_ControlBlock     *procPtr;
  830.  
  831.     if (debugProcStubs) {
  832.     printf("Proc_SetreuidStub\n");
  833.     }
  834.     procPtr = Proc_GetEffectiveProc();
  835.     if (userID == -1 || userID == PROC_NO_ID) {
  836.     userID = procPtr->userID;;
  837.     }
  838.     if (effUserID == -1 || effUserID == PROC_NO_ID) {
  839.     effUserID = procPtr->effectiveUserID;
  840.     }
  841.     if (userID != procPtr->userID && userID != procPtr->effectiveUserID &&
  842.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  843.     Mach_SetErrno(Compat_MapCode(PROC_UID_MISMATCH));
  844.     return -1;
  845.     }
  846.     if (effUserID != procPtr->userID && effUserID != procPtr->effectiveUserID &&
  847.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  848.     Mach_SetErrno(Compat_MapCode(PROC_UID_MISMATCH));
  849.     return -1;
  850.     }
  851.     procPtr->userID = userID;
  852.     procPtr->effectiveUserID = effUserID;
  853.     if (procPtr->state == PROC_MIGRATED) {
  854.     status = Proc_MigUpdateInfo(procPtr);
  855.     if (status != SUCCESS) {
  856.         Mach_SetErrno(Compat_MapCode(status));
  857.         return -1;
  858.     }
  859.     }
  860.     return 0;
  861. }
  862.  
  863.  
  864.  
  865. /*
  866.  *----------------------------------------------------------------------
  867.  *
  868.  * Proc_SetregidStub --
  869.  *
  870.  *    The stub for the "setregid" Unix system call.
  871.  *
  872.  * Results:
  873.  *    Returns -1 on failure.
  874.  *
  875.  * Side effects:
  876.  *    Side effects associated with the system call.
  877.  *     
  878.  *
  879.  *----------------------------------------------------------------------
  880.  */
  881. int
  882. Proc_SetregidStub(rgid, egid)
  883.     int    rgid, egid;
  884. {
  885.     int        array[2];
  886.     int        num = 0;
  887.     Proc_ControlBlock     *procPtr;
  888.     Fs_ProcessState     *fsPtr;
  889.     int i;
  890.  
  891.     if (debugProcStubs) {
  892.     printf("Proc_SetregidStub\n");
  893.     }
  894.     if (rgid != -1) {
  895.     array[0] = rgid;
  896.     num = 1;
  897.     if (egid != rgid && egid != -1) {
  898.         array[1] = egid;
  899.         num++;
  900.     }
  901.     } else if (egid != -1) {
  902.     array[0] = egid;
  903.     num++;
  904.     }
  905.     if (num > 0) {
  906.     /*
  907.      * Need to protect against abritrary group setting.
  908.      */
  909.     procPtr = Proc_GetEffectiveProc();
  910.     if (procPtr->effectiveUserID != 0) {
  911.         Mach_SetErrno(EPERM);
  912.         return -1;
  913.     }
  914.  
  915.     /*
  916.      *  If the current group ID table is too small, allocate space
  917.      *    for a larger one.
  918.      */
  919.     fsPtr = procPtr->fsPtr;
  920.     if (fsPtr->numGroupIDs < num) {
  921.         free((Address) fsPtr->groupIDs);
  922.         fsPtr->groupIDs = (int *) malloc(num * sizeof(int));
  923.     }
  924.     for (i = 0; i < num; i++) {
  925.         fsPtr->groupIDs[i] = array[i];
  926.     }  
  927.     fsPtr->numGroupIDs = num;
  928.     }
  929.     return 0;
  930. }
  931.  
  932.  
  933.  
  934. /*
  935.  *----------------------------------------------------------------------
  936.  *
  937.  * Proc_GetrlimitStub --
  938.  *
  939.  *    The stub for the "getrlimit" Unix system call.
  940.  *
  941.  * Results:
  942.  *    Returns -1 on failure.
  943.  *
  944.  * Side effects:
  945.  *    Side effects associated with the system call.
  946.  *     
  947.  *
  948.  *----------------------------------------------------------------------
  949.  */
  950. int
  951. Proc_GetrlimitStub()
  952. {
  953.  
  954.     printf("Proc_Getrlimit not implemented\n");
  955.     return 0;
  956. }
  957.  
  958.  
  959. /*
  960.  *----------------------------------------------------------------------
  961.  *
  962.  * Proc_SetrlimitStub --
  963.  *
  964.  *    The stub for the "setrlimit" Unix system call.
  965.  *
  966.  * Results:
  967.  *    Returns -1 on failure.
  968.  *
  969.  * Side effects:
  970.  *    Side effects associated with the system call.
  971.  *     
  972.  *
  973.  *----------------------------------------------------------------------
  974.  */
  975. int
  976. Proc_SetrlimitStub()
  977. {
  978.  
  979.     printf("Proc_Setrlimit not implemented\n");
  980.     return 0;
  981. }
  982.  
  983.  
  984. #define COPYTIME(TO,FROM) { \
  985.         (TO).tv_sec = (FROM).seconds; \
  986.         (TO).tv_usec = (FROM).microseconds; \
  987.       }
  988.  
  989.  
  990. /*
  991.  *----------------------------------------------------------------------
  992.  *
  993.  * Proc_GetrusageStub --
  994.  *
  995.  *    The stub for the "getrusage" Unix system call.
  996.  *
  997.  * Results:
  998.  *    Returns -1 on failure.
  999.  *
  1000.  * Side effects:
  1001.  *    Side effects associated with the system call.
  1002.  *     
  1003.  *
  1004.  *----------------------------------------------------------------------
  1005.  */
  1006. int
  1007. Proc_GetrusageStub(who, rusage)
  1008.     int who;
  1009.     struct rusage *rusage;
  1010. {
  1011.     Proc_ResUsage spriteUsage;         /* sprite resource usage buffer */
  1012.     struct rusage unixUsage;
  1013.     register Proc_ControlBlock     *procPtr;
  1014.     ReturnStatus status;
  1015.  
  1016.     if (debugProcStubs) {
  1017.     printf("Proc_GetrusageStub\n");
  1018.     }
  1019.  
  1020.     procPtr = Proc_GetEffectiveProc();
  1021.     if (procPtr == (Proc_ControlBlock *) NIL) {
  1022.     panic("Proc_GetResUsage: procPtr == NIL\n");
  1023.     } 
  1024.     Proc_Lock(procPtr);
  1025.     Timer_TicksToTime(procPtr->kernelCpuUsage.ticks,
  1026.     &spriteUsage.kernelCpuUsage);
  1027.     Timer_TicksToTime(procPtr->userCpuUsage.ticks, &spriteUsage.userCpuUsage);
  1028.     Timer_TicksToTime(procPtr->childKernelCpuUsage.ticks,
  1029.     &spriteUsage.childKernelCpuUsage);
  1030.     Timer_TicksToTime(procPtr->childUserCpuUsage.ticks,
  1031.     &spriteUsage.childUserCpuUsage);
  1032.     spriteUsage.numQuantumEnds = procPtr->numQuantumEnds;
  1033.     spriteUsage.numWaitEvents     = procPtr->numWaitEvents;
  1034.     Proc_Unlock(procPtr);
  1035.     if (who == RUSAGE_SELF) {
  1036.     COPYTIME(unixUsage.ru_utime, spriteUsage.userCpuUsage);
  1037.     COPYTIME(unixUsage.ru_stime, spriteUsage.kernelCpuUsage);
  1038.     } else {
  1039.     COPYTIME(unixUsage.ru_utime, spriteUsage.childUserCpuUsage);
  1040.     COPYTIME(unixUsage.ru_stime, spriteUsage.childKernelCpuUsage);
  1041.     }
  1042.     unixUsage.ru_maxrss = 0;
  1043.     unixUsage.ru_ixrss = 0;    /* integral shared memory size */
  1044.     unixUsage.ru_idrss = 0;    /* integral unshared data size */
  1045.     unixUsage.ru_isrss = 0;    /* integral unshared stack size */
  1046.     unixUsage.ru_minflt = 0;    /* page reclaims */
  1047.     unixUsage.ru_majflt = 0;    /* page faults */
  1048.     unixUsage.ru_nswap = 0;    /* swaps */
  1049.     unixUsage.ru_inblock = 0;    /* block input operations */
  1050.     unixUsage.ru_oublock = 0;    /* block output operations */
  1051.     unixUsage.ru_msgsnd = 0;    /* messages sent */
  1052.     unixUsage.ru_msgrcv = 0;    /* messages received */
  1053.     unixUsage.ru_nsignals = 0;    /* signals received */
  1054.     unixUsage.ru_nvcsw =
  1055.         spriteUsage.numWaitEvents;  /* voluntary context switches */
  1056.     unixUsage.ru_nivcsw =
  1057.         spriteUsage.numQuantumEnds;  /* involuntary context switches */
  1058.     status = Vm_CopyOut(sizeof(unixUsage), (Address)&unixUsage, 
  1059.               (Address)rusage);
  1060.     if (status != SUCCESS) {
  1061.     Mach_SetErrno(Compat_MapCode(status));
  1062.     return -1;
  1063.     }
  1064.     return 0;
  1065. }
  1066.  
  1067.  
  1068. /*
  1069.  *----------------------------------------------------------------------
  1070.  *
  1071.  * Proc_GetitimerStub --
  1072.  *
  1073.  *    The stub for the "getitimer" Unix system call.
  1074.  *
  1075.  * Results:
  1076.  *    Returns -1 on failure.
  1077.  *
  1078.  * Side effects:
  1079.  *    Side effects associated with the system call.
  1080.  *     
  1081.  *
  1082.  *----------------------------------------------------------------------
  1083.  */
  1084. int
  1085. Proc_GetitimerStub(which, value)
  1086.     int which;
  1087.     struct itimerval *value;
  1088. {
  1089.     ReturnStatus    status;
  1090.  
  1091.     if (debugProcStubs) {
  1092.     printf("Proc_GetitimerStub\n");
  1093.     }
  1094.     status = Proc_GetIntervalTimer(which, (Proc_TimerInterval *) value);
  1095.     if (status != SUCCESS) {
  1096.     Mach_SetErrno(Compat_MapCode(status));
  1097.     return -1;
  1098.     }
  1099.     return 0;
  1100. }
  1101.  
  1102.  
  1103. /*
  1104.  *----------------------------------------------------------------------
  1105.  *
  1106.  * Proc_SetitimerStub --
  1107.  *
  1108.  *    The stub for the "setitimer" Unix system call.
  1109.  *
  1110.  * Results:
  1111.  *    Returns -1 on failure.
  1112.  *
  1113.  * Side effects:
  1114.  *    Side effects associated with the system call.
  1115.  *     
  1116.  *
  1117.  *----------------------------------------------------------------------
  1118.  */
  1119. int
  1120. Proc_SetitimerStub(which, value, ovalue)
  1121.  
  1122.     int which;
  1123.     struct itimerval *value;
  1124.     struct itimerval *ovalue;
  1125. {
  1126.     ReturnStatus    status;
  1127.  
  1128.     if (debugProcStubs) {
  1129.     printf("Proc_SetitimerStub\n");
  1130.     }
  1131.     status = Proc_SetIntervalTimer(which, (Proc_TimerInterval *) value,
  1132.                  (Proc_TimerInterval *) ovalue);
  1133.     if (status != SUCCESS) {
  1134.     Mach_SetErrno(Compat_MapCode(status));
  1135.     return -1;
  1136.     }
  1137.     return 0;
  1138. }
  1139.  
  1140. /*
  1141.  *----------------------------------------------------------------------
  1142.  *
  1143.  * Proc_Wait3Stub --
  1144.  *
  1145.  *    The stub for the "wait3" Unix system call.
  1146.  *
  1147.  * Results:
  1148.  *    Returns -1 on failure.
  1149.  *
  1150.  * Side effects:
  1151.  *    Side effects associated with the system call.
  1152.  *     
  1153.  *
  1154.  *----------------------------------------------------------------------
  1155.  */
  1156. int
  1157. Proc_Wait3Stub(statusPtr, options, unixRusagePtr)
  1158.     union    wait    *statusPtr;
  1159.     int            options;
  1160.     struct    rusage    *unixRusagePtr;
  1161. {
  1162.     if (debugProcStubs) {
  1163.     printf("Proc_Wait4Stub(%x, %x, %x)\n", statusPtr, options,
  1164.         unixRusagePtr);
  1165.     }
  1166.     return Proc_Wait4Stub(0, statusPtr, options, unixRusagePtr);
  1167. }
  1168.  
  1169. #if defined(ds3100) || defined(ds5000)
  1170. /*
  1171.  *----------------------------------------------------------------------
  1172.  *
  1173.  * Proc_WaitpidStub --
  1174.  *
  1175.  *    The stub for the "waitpid" Unix system call.
  1176.  *
  1177.  * Results:
  1178.  *    Returns -1 on failure.
  1179.  *
  1180.  * Side effects:
  1181.  *    Side effects associated with the system call.
  1182.  *     
  1183.  *
  1184.  *----------------------------------------------------------------------
  1185.  */
  1186. int
  1187. Proc_WaitpidStub(pid, statusPtr, options)
  1188.     int            pid;
  1189.     union    wait    *statusPtr;
  1190.     int            options;
  1191. {
  1192.     if (pid==-1) {
  1193.     pid = 0;
  1194.     } else if (pid==0) {
  1195.     pid = -Proc_GetpgrpStub(pid);
  1196.     }
  1197.     return Proc_Wait4Stub(pid, statusPtr, options, 0);
  1198. }
  1199. #endif
  1200.